package be.ipl.finito.usecasesimpl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.Stateless;

import be.ipl.finito.dao.GrilleDao;
import be.ipl.finito.dao.JoueurDao;
import be.ipl.finito.dao.PartieDao;
import be.ipl.finito.domaine.Grille;
import be.ipl.finito.domaine.Jeton;
import be.ipl.finito.domaine.Joueur;
import be.ipl.finito.domaine.Partie;
import be.ipl.finito.domaine.Partie.Etat;
import be.ipl.finito.usecases.GestionPartie;
import be.ipl.finito.util.Util;

@Stateless
public class GestionPartieImpl implements GestionPartie {
	@EJB
	JoueurDao jdao;

	@EJB
	PartieDao pdao;
	
	@EJB
	GrilleDao gdao;

	@Override
	public Partie chargerTout(Partie partie) {
		Util.checkObject(partie);
		//partie = this.pdao.chargerGrilles(partie);
		return this.pdao.chargerGrilles(partie);
	}

	@Override
	public boolean commencerPartie(Partie partie) {
		Util.checkObject(partie);
		//partie = this.pdao.rechercher(partie.getId());
		//partie = this.chargerTout(partie);

//		if (partie.getGrillesDesJoueurs().size() < 2) {
//			return false;
//		}

		return partie.lancerPartie();
	}

	@Override
	public Partie creerPartie(String nom) {
		if (this.pdao.rechercher(nom) != null) {
			return null;
		}

		Partie partie = new Partie(nom);
		//partie = this.pdao.enregistrer(partie);
		return this.pdao.enregistrer(partie);
	}

	@Override
	public boolean estEnCours(Partie partie) {
		Util.checkObject(partie);
		//partie = this.pdao.rechercher(partie.getId());
		return partie.getEtat() == Etat.EN_COURS;
	}

	@Override
	public List<Joueur> calculerVainqueur(Partie partie) {
		Util.checkObject(partie);
		partie = this.chargerTout(partie);
		return partie.determinerVaiqueur();
	}

	@Override
	@Lock(LockType.READ)
	public List<Joueur> listerJoueurs(Partie partie) {
		Util.checkObject(partie);
		if (partie.getGrillesDesJoueurs() == null) {
			return null;
		}
		List<Joueur> joueurs = new ArrayList<Joueur>();
		// partie = this.pdao.rechercher(partie.getId());

		for (Grille g : partie.getGrillesDesJoueurs()) {
			joueurs.add(g.getProprietaire());
		}
		return joueurs;
	}

	@Override
	public boolean lancerDe(Partie partie) {

		this.pdao.mettreAJour(partie);
		return true;
	}

	@Override
	@Lock(LockType.READ)
	public List<Partie> listerParties() {
		return this.pdao.lister();
	}

	@Override
	@Lock(LockType.READ)
	public List<Partie> listerPartiesEnAttente() {
		return this.pdao.listerPartiesEtat(Etat.EN_ATTENTE);
	}

	@Override
	@Lock(LockType.READ)
	public Partie rechercherPartie(int id) {
		return this.pdao.rechercher(id);
	}

	@Override
	@Lock(LockType.READ)
	public Partie rechercherPartie(String nom) {
		return this.pdao.rechercher(nom);
	}

	@Override
	public boolean rejoindrePartie(Partie partie, Joueur joueur) {
		// if (partie == null) {
		// return false;
		// }

		// partie = this.pdao.rechercher(partie.getId());
		// partie = this.chargerTout(partie);

		if (partie.inscrireJoueur(new Grille(joueur, partie))) {
			/*
			 * if (partie.getGrillesDesJours().size() >= Partie.MAX_JOUEURS) {
			 * partie.lancerPartie(); }
			 */
			return true;
		}
		return false;
	}

	@Override
	public boolean rejoindrePartie(Partie partie, Grille grille) {
		return partie.inscrireJoueur(grille);
	}

	@Override
	public boolean terminerPartie(Partie partie) {
		Util.checkObject(partie);
		// partie = this.pdao.rechercher(partie.getId());
		if (partie.terminePartie()) {
			partie = null;
			return true;
		}
		return false;
	}

	@Override
	public Grille getGrille(Partie partie, Joueur joueur) {
		Util.checkObject(partie);
		Util.checkObject(joueur);
		// partie = pdao.rechercher(partie.getId());
		Iterator<Grille> it = partie.getGrillesDesJoueurs().iterator();
		while (it.hasNext()) {
			Grille g = it.next();
			if (g.getProprietaire().equals(joueur))
				return g;
		}
		return null;
	}
	
	@Override
	public int nombreJoueurs(Partie p){
		Util.checkObject(p);
		return p.getNombreJoueurs();
	}

	@Override
	public Partie modifierEtatPartie(Partie partie) {
		Util.checkObject(partie);
		return pdao.mettreAJour(partie);
	}

	@Override
	public boolean ajouterUnJetonJoue(Jeton jeton, Partie partie,
			int positionChoisieParLeServeur) {
	
		return partie.ajouterUnJetonJoue(jeton, positionChoisieParLeServeur);
	}
}
